#include "scenario.h"

Scenario::Scenario(const char *name, Job *job, Grid *grid, int numberOfExecutions, long double seed, long double error_rate) {
	this->adaptivePartioner = NULL;
	this->name = new char[strlen(name)+1];
	this->name = strcpy((char *)this->name, name);
	this->grid = grid;
	this->job = job;
	this->numberOfExecutions = numberOfExecutions;
	this->seed = seed;
	this->error_rate = error_rate;
}

Scenario::~Scenario() {
	if (this->name) delete this->name;
	if (job!=NULL) delete job;
	if (grid!=NULL) delete grid;
	
	this->name = NULL;
	this->job = NULL;
	this->grid = NULL;
}

const char *Scenario::getName() {
	return this->name;
}

void Scenario::setGrid(Grid *newGrid) {
	this->grid = newGrid;
}

Grid *Scenario::getGrid() {
	return this->grid;
}

void Scenario::setJob(Job *newJob) {
	this->job = newJob;
}

Job *Scenario::getJob() {
	return this->job;
}

void Scenario::setNumberOfExecutions (int executions) {
	this->numberOfExecutions = executions;
}

int Scenario::getNumberOfExecutions() {
	return this->numberOfExecutions;
}

void Scenario::setSeed(long double seed) {
	this->seed = seed;
}

long double Scenario::getSeed() {
	return this->seed;
}

void Scenario::setJobInputSize(long double jobInputSize) {
	this->jobInputSize = jobInputSize;
}

long double Scenario::getJobInputSize() {
	return this->jobInputSize;
}

void Scenario::setAverageTaskInputSize(long double size) {
	this->averageTaskInputSize = size;
}

long double Scenario::getAverageTaskInputSize() {
	return this->averageTaskInputSize;
}

void Scenario::setInputHeterogeneity(long double het) {
	this->inputHeterogeneity = het;
}

long double Scenario::getInputHeterogeneity() {
	return this->inputHeterogeneity;
}

void Scenario::setAverageTaskOutputSize(long double size) {
	this->averageTaskOutputSize = size;
}

long double Scenario::getAverageTaskOutputSize() {
	return this->averageTaskOutputSize;
}

void Scenario::setOutputHeterogeneity(long double het) {
	this->outputHeterogeneity = het;
}

long double Scenario::getOutputHeterogeneity() {
	return this->outputHeterogeneity;
}

void Scenario::setGridSpeed(long double speed) {
	this->gridSpeed = speed;
}

long double Scenario::getGridSpeed() {
	return this->gridSpeed;
}

void Scenario::setGridHeterogeneity(long double het) {
	this->gridHeterogeneity = het;
}

long double Scenario::getGridHeterogeneity() {
	return this->gridHeterogeneity;
}

void Scenario::setAdaptivePartioner(AdaptivePartitioner *partioner) {
	this->adaptivePartioner = partioner;
}
AdaptivePartitioner* Scenario::getAdaptivePartioner() {
	return this->adaptivePartioner;
}
void Scenario::setErrorRate(long double error_rate) {
	this->error_rate = error_rate;
}


long double Scenario::getErrorRate() {
	return this->error_rate;
}

void Scenario::writeToXML(const char *scenario_desc) {
	/* File descriptor to XML*/
	FILE *xmlFile;
	/*Open the file */
	xmlFile = fopen(scenario_desc, "w");
	
	//Begin to write tags
	//////////////////////
	
	/* Write the header */
	fprintf(xmlFile, "<?xml version=\"1.0\"?>\n");
	/* The root node (Scenario)*/
	fprintf(xmlFile, "<Scenario name=\"%s\" numberOfExecutions=\"%d\" seed=\"%Lf\" errorRate=\"%Lf\">\n", this->name, this->numberOfExecutions, this->seed, this->error_rate);

	fprintf(xmlFile, "\t<ApplicationInputSize value=\"%Lf\" />\n", this->jobInputSize);	
	fprintf(xmlFile, "\t<DataInputGroup value=\"%Lf\" />\n", this->averageTaskInputSize);		
	fprintf(xmlFile, "\t<DataOutputGroup value=\"%Lf\" />\n", this->averageTaskOutputSize);			
	fprintf(xmlFile, "\t<InputAH value=\"%Lf\" />\n", this->inputHeterogeneity);			
	fprintf(xmlFile, "\t<OutputAH value=\"%Lf\" />\n", this->outputHeterogeneity);				
	fprintf(xmlFile, "\t<GridSpeed value=\"%Lf\" />\n", this->gridSpeed);			
	fprintf(xmlFile, "\t<GridHeterogeneity value=\"%Lf\" />\n", this->gridHeterogeneity);				

	/*Job tag*/
	fprintf(xmlFile, "\t<Job  name=\"%s\" numberOfTasks=\"%d\" input_tpt=\"%Lf\" output_tpt=\"%Lf\">\n",this->job->getName(), this->job->getNumberOfTasks(), this->job->getInputTpt(), this->job->getOutputTpt());	
	
	/*Tasks*/
	for (int n=0; n<this->job->getNumberOfTasks(); n++) {
		Task *task = this->job->getTaskByIndex(n);
		fprintf(xmlFile, "\t\t<Task name=\"%s\" inputDataSize=\"%Lf\" outputDataSize=\"%Lf\" />\n", task->getName(), task->getDataInput()->getSize(), task->getDataOutput()->getSize());		
	}
	/* Closing theJob tag */
	fprintf(xmlFile, "\t</Job>\n");

	/*Grid tag*/
	fprintf(xmlFile, "\t<Grid name=\"%s\" numberOfSites=\"%d\" numberOfLinks=\"%d\" >\n", this->grid->getName(), this->grid->getNumberOfSites(), grid->getNumberOfLinks());		
	
	/*Site tags*/
	for (int i = 0; i<this->grid->getNumberOfSites(); i++) {
		Site *s = this->grid->getSiteByIndex(i);
		fprintf(xmlFile,"\t\t<Site name=\"%s\" numberOfProcessors=\"%d\" link_bandwidth_trace=\"%s\" link_bandwidth_error=\"%s\" linkoffset=\"%Lf\" >\n",s->getDomain(), s->getNumberOfProcessors(), s->getLink()->getBandwidthTrace(), s->getLink()->getBandwidthError(), s->getLink()->getBandwidthOffset());//, s->getLink()->getBandwidthForecast());
		/*Processors*/
		for (int j= 0; j<s->getNumberOfProcessors(); j++) {
			Processor *p = s->getProcessorByIndex(j);
			fprintf(xmlFile, "\t\t\t<Processor name=\"%s\"  trace=\"%s\" cpuoffset=\"%Lf\" cpuspeed=\"%Lf\" error=\"%s\"/>\n", p->getName(), p->getCpuAvailableTrace(), p->getCpuOffset(), p->getCpuSpeed(), /*p->getCpuAvailableForecast(),*/ p->getCpuAvailableErrorTrace());
		}
		fprintf(xmlFile, "\t\t</Site>\n");										
	}
	
	/*Links tag*/
	for (int k = 0; k<grid->getNumberOfLinks(); k++) {
		Link *l = grid->getLinkByIndex(k);
		fprintf(xmlFile, "\t\t<Link name=\"%s\" lat_trace=\"%s\" bandwidth_trace=\"%s\" bandwidthlimit_trace=\"%s\" lat_error=\"%s\" bandwidth_error=\"%s\" linkoffset=\"%Lf\" />\n", l->getName(), l->getLatencyTrace(), l->getBandwidthTrace(), l->getBandwidthLimitTrace(), l->getLatencyError(), l->getBandwidthError(), l->getBandwidthOffset());
	}

	/*Adaptive Partioner*/
	if (this->getAdaptivePartioner()!=NULL)	{

		fprintf(xmlFile, "\t<AdaptivePartioner value=\"1\">\n");
    	fprintf(xmlFile,"\t\t<GI value=\"%Lf\" />\n", this->getAdaptivePartioner()->granularity_initial);
    	fprintf(xmlFile,"\t\t<GF value=\"%Lf\" />\n", this->getAdaptivePartioner()->granularity_final);
    	fprintf(xmlFile,"\t\t<DI value=\"%Lf\" />\n", this->getAdaptivePartioner()->percentage_startup);
    	fprintf(xmlFile,"\t\t<DR value=\"%Lf\" />\n", this->getAdaptivePartioner()->percentage_calisteady);
    	fprintf(xmlFile,"\t\t<V value=\"%Lf\" />\n", this->getAdaptivePartioner()->variance);
    	fprintf(xmlFile,"\t\t<W value=\"%d\" />\n", this->getAdaptivePartioner()->speed_window);

	} else {
		fprintf(xmlFile, "\t<AdaptivePartioner value=\"0\">\n");		
	}


	fprintf(xmlFile, "\t</AdaptivePartioner>\n");		    
	
	
	/*Closing Grid tag*/
	fprintf(xmlFile, "\t</Grid>\n");		
	
	
	/* Closing the Scenario tag */
	fprintf(xmlFile, "</Scenario>\n");
	
	//End fo write tags
	//////////////////
	
	/*Close the file*/
	fclose(xmlFile);	
	

}
